

#include "state.h"
#include "instruction.h"

#include <kernel/kernel.h>
#include <kernel/block/block.h>

extern vm_State *vm_state_request (vm_Agent *_agent)
{
	vm_State *state;

	state = (vm_State *) block_request (sizeof (vm_State));
	state->Agent = _agent;
	state->InstructionPointer = _agent->CodeSegment;
	state->StackTop = 0;

	++_agent->ReferenceCount;

	return state;
}


extern void vm_state_release (vm_State *_state)
{
	--_state->Agent->ReferenceCount;
	block_release (_state);
}


extern int vm_state_pop (vm_State *_state, handle _queue)
{
	return handle_read (_queue, (char *) _state, sizeof (vm_State));
}


extern int vm_state_push (const vm_State *_state, handle _queue)
{
	return handle_write (_queue, (char *) _state, sizeof (vm_State));
}


extern int vm_state_resume (vm_State *_state, int _steps)
{
	int i;
	int word;
	vm_Instruction *inst;

	for (i = 0; i < _steps; ++i)
	{	
		word = *_state->InstructionPointer;

		inst = vm_instruction_opcode (vm_instruction_getop (word));

		if (inst == NULL)
		{
			return -1;
		}

		switch (inst->Format)
		{
		case VM_INSTRUCTION_ABC :

			inst->Callback.ABC (_state, vm_instruction_getA (word), vm_instruction_getB (word), vm_instruction_getC (word));
			break;
		case VM_INSTRUCTION_ABx :

			inst->Callback.ABx (_state, vm_instruction_getA (word), vm_instruction_getBx (word));
			break;
		}
	}

	return 0;
}

